package com.jytc.framework.bo.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.jytc.framework.bo.FwUserBO;
import com.jytc.framework.commons.Page;
import com.jytc.framework.commons.PropertyFilter;
import com.jytc.framework.commons.PropertyFilter.MatchType;
import com.jytc.framework.constants.CommonConstants;
import com.jytc.framework.constants.ResultConstants;
import com.jytc.framework.dao.FwDeptDAO;
import com.jytc.framework.dao.FwRoleDAO;
import com.jytc.framework.dao.FwUserDAO;
import com.jytc.framework.dao.FwUserRoleDAO;
import com.jytc.framework.dto.FwUserDTO;
import com.jytc.framework.po.FwDept;
import com.jytc.framework.po.FwRole;
import com.jytc.framework.po.FwUser;
import com.jytc.framework.po.FwUserRole;
import com.jytc.framework.utils.CommonUtils;

/**
 * @title: FSysUserBOImpl.java
 * @description: 用户管理业务操作类
 * 
 * @author: dongyuese
 *
 */
public class FwUserBOImpl implements FwUserBO
{
	/**
	 * 用户登录信息数据访问对象
	 */
	@Autowired
	private FwUserDAO fwUserDAO;

	/**
	 * 单位信息数据访问对象
	 */
	@Autowired
	private FwDeptDAO fwDeptDAO;

	/**
	 * 用户角色关联信息数据访问对象
	 */
	@Autowired
	private FwUserRoleDAO fwUserRoleDAO;

	/**
	 * 角色信息数据访问对象
	 */
	@Autowired
	private FwRoleDAO fwRoleDAO;

	/**
	 * 按照条件分页查询用户信息
	 * @param page　分页信息
	 * @param filters　过滤条件列表
	 * @return　用户信息集合
	 * @throws Exception
	 */
	public Page query(Page page, List<PropertyFilter> filters) throws Exception
	{
		Page pageTemp = fwUserDAO.findByPage(page, filters);
		List tempList = pageTemp.getResult();
		List resultList = new ArrayList();
		if (tempList != null)
		{
			FwUser fwUser = null;
			FwDept tempDept = null;
			for (int i = 0; i < tempList.size(); i++)
			{
				fwUser = (FwUser) tempList.get(i);
				FwUserDTO fwUserDTO = new FwUserDTO();
				BeanUtils.copyProperties(fwUserDTO, fwUser);
				tempDept = fwDeptDAO.findById(fwUser.getDeptId());
				fwUserDTO.setCorpName(tempDept.getDeptName());
				resultList.add(fwUserDTO);
			}
		}
		pageTemp.setResult(resultList);
		return pageTemp;
	}

	/**
	 * 保存用户信息
	 * @param sysLoginDTO　用户信息数据传输对象
	 * @return　保存成功或失败
	 * @throws Exception
	 */
	@Transactional(readOnly = false, rollbackFor = Throwable.class)
	public int save(FwUserDTO fwUserDTO) throws Exception
	{
		String roleIds = CommonUtils.arrayToString(fwUserDTO.getRoles(), CommonConstants.SPLIT_SYMBOL_COMMA);
		FwUser fwUser = new FwUser();
		BeanUtils.copyProperties(fwUser, fwUserDTO);

		//判断是否已经存在同名用户
		if (fwUserDAO.findUnique("loginName", fwUserDTO.getUserName()) != null)
		{
			return CommonConstants.USER_IS_EXIST;
		}

		//如果新增的是管理员帐号，则需要判断是否在对应的单位下已经存在管理员
		if (CommonConstants.USER_TYPE_1 == fwUserDTO.getUserType())
		{
			if (this.validatonUserType(fwUserDTO.getDeptId(), fwUserDTO.getUserType()))
			{
				return CommonConstants.USER_TYPE_1_CORP_IS_EXIST;
			}
		}

		//保存用户信息
		fwUserDAO.save(fwUser);

		//保存用户角色关联信息
		this.saveLoginRole(roleIds, fwUser);
		return ResultConstants.INSERT_SUCCEED;
	}

	/**
	 * 保存用户角色关联信息
	 * @param roleIds　角色ID，以逗号分隔
	 * @param sysRole 角色信息
	 */
	private void saveLoginRole(String roleIds, FwUser fwUser)
	{
		//批量保存用户角色联信息
		String[] roleArr = roleIds.split(CommonConstants.SPLIT_SYMBOL_COMMA);
		List<FwUserRole> userRoleList = new ArrayList<FwUserRole>();
		for (String roleId : roleArr)
		{
			FwUserRole userRole = new FwUserRole();
			userRole.setFwUser(fwUser);
			userRole.setFwRole(new FwRole(Integer.valueOf(roleId)));

			//用户角色关联信息表中状态字段为预留，先默认为0，无实际意义
			userRole.setStatus(Integer.valueOf(0));
			userRoleList.add(userRole);
		}
		fwUserRoleDAO.saveAll(userRoleList);
	}

	/**
	 * 根据登录ID查询用户信息
	 * @param loginId　登录ID
	 * @return
	 * @throws Exception
	 */
	public FwUserDTO findById(Integer userId) throws Exception
	{
		FwUser fwUser = fwUserDAO.findById(userId);
		FwUserDTO fwUserDTO = new FwUserDTO();
		BeanUtils.copyProperties(fwUserDTO, fwUser);

		StringBuilder roleIds = new StringBuilder();
		//将角色ID拼装成字符串，以逗号分隔，供修改页面初始化展示用
		for (FwUserRole fwUserRole : fwUserDTO.getFwUserRoles())
		{
			roleIds.append(fwUserRole.getFwRole().getRoleId()).append(CommonConstants.SPLIT_SYMBOL_COMMA);
		}
		fwUserDTO.setRoleIds(roleIds.toString());

		return fwUserDTO;
	}

	/**
	 * 修改用户信息
	 * @param sysLoginDTO　用户信息数据传输对象
	 * @return 保存成功或失败
	 * @throws Exception
	 */
	@Transactional(readOnly = false, rollbackFor = Throwable.class)
	public int update(FwUserDTO fwUserDTO) throws Exception
	{
		FwUser fwUserTemp = fwUserDAO.findById(fwUserDTO.getUserId());

		//删除用户角色关联信息
		fwUserTemp.getFwUserRoles().remove(fwUserTemp);

		String roleIds = CommonUtils.arrayToString(fwUserDTO.getRoles(), CommonConstants.SPLIT_SYMBOL_COMMA);
		//保存用户角色关联信息
		this.saveLoginRole(roleIds, fwUserTemp);

		//更新用户信息
		BeanUtils.copyProperties(fwUserTemp, fwUserDTO);
		fwUserDAO.update(fwUserTemp);
		return ResultConstants.UPDATE_SUCCEED;
	}

	/**
	 * 根据用户ID删除用户信息
	 * @param loginId 用户ID
	 * @return　删除成功或失败
	 * @throws Exception
	 */
	@Transactional(readOnly = false, rollbackFor = Throwable.class)
	public int deleteById(Integer userId) throws Exception
	{
		fwUserDAO.deleteById(userId);
		return ResultConstants.DELETE_SUCCEED;
	}

	/**
	 * 批量删除用户信息
	 * @param loginIds　用户ID集合
	 * @return　删除成功或失败
	 * @throws Exception
	 */
	@Transactional(readOnly = false, rollbackFor = Throwable.class)
	public int deleteByIds(Integer[] loginIds) throws Exception
	{
		for (Integer loginId : loginIds)
		{
			fwUserDAO.deleteById(loginId);
		}
		return ResultConstants.DELETE_SUCCEED;
	}

	/**
	 * 根据单位ID以及用户的有效性获取用户信息集合，如果validTag为空，则默认获取该单位下所有用户
	 * @param corpId　单位ID
	 * @param validTag　有效标志
	 * @return　用户信息集合
	 * @throws Exception
	 */
	public List<FwUser> queryByCorpAndValidTag(Integer corpId, String validTag) throws Exception
	{
		List<PropertyFilter> filterList = new ArrayList<PropertyFilter>();
		filterList.add(new PropertyFilter(MatchType.EQ + "_corpId", corpId));

		//如果validTag不为空，则添加是否有效过滤条件
		if ((validTag != null) && (!"".equals(validTag)))
		{
			filterList.add(new PropertyFilter(MatchType.EQ + "_validTag", validTag));
		}
		return fwUserDAO.findByFilters(filterList);
	}

	/**
	 * 根据角色ID，获取所有引用该角色的用户信息
	 * @param roleId　角色ID
	 * @return　用户信息集合
	 * @throws Exception
	 */
	public List<FwUser> queryByRoleId(Integer roleId) throws Exception
	{
		FwRole fwRole = fwRoleDAO.findById(roleId);
		List<FwUser> fwLoginList = new ArrayList<FwUser>();
		for (FwUserRole fwLoginRole : fwRole.getFwUserRoles())
		{
			fwLoginList.add(fwLoginRole.getFwUser());
		}
		return fwLoginList;
	}

	/**
	 * 根据单位ID、用户类型查询用户信息，主要用于一个单位下只能存在一个系统管理员的判断
	 * @param corpId　单位ID
	 * @param userType　用户类型
	 * @return　用户信息集合
	 * @throws Exception
	 */
	public List<FwUser> queryByCorpAndType(Integer corpId, Integer userType) throws Exception
	{
		List<PropertyFilter> filterList = new ArrayList<PropertyFilter>();
		filterList.add(new PropertyFilter(MatchType.EQ + "_corpId", corpId));
		filterList.add(new PropertyFilter(MatchType.EQ + "_userType", userType));
		return fwUserDAO.findByFilters(filterList);
	}

	/**
	 * 检验在指定单位下是否已经存在管理员帐号，如果存在则返回true，否则返回false
	 * @param corpId
	 * @param userType
	 * @return
	 * @throws Exception
	 */
	private boolean validatonUserType(Integer deptId, Integer userType) throws Exception
	{
		List<FwUser> fwLoginList = this.queryByCorpAndType(deptId, userType);
		if ((fwLoginList == null) || (fwLoginList.isEmpty()))
		{
			return false;
		}
		return true;
	}
}
